package com.pzhuweb.sgblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pzhuweb.sgblog.domain.dto.AddUserDto;
import com.pzhuweb.sgblog.domain.dto.UserDto;
import com.pzhuweb.sgblog.domain.dto.UserStatusDto;
import com.pzhuweb.sgblog.domain.entity.Role;
import com.pzhuweb.sgblog.domain.entity.User;
import com.pzhuweb.sgblog.domain.enums.AppHttpCodeEnum;
import com.pzhuweb.sgblog.domain.utils.BeanCopyUtils;
import com.pzhuweb.sgblog.domain.utils.ResponseResult;
import com.pzhuweb.sgblog.domain.vo.AdminUserVo;
import com.pzhuweb.sgblog.domain.vo.PageVo;
import com.pzhuweb.sgblog.domain.vo.UserInfoVo;
import com.pzhuweb.sgblog.exception.SystemException;
import com.pzhuweb.sgblog.mapper.RoleMapper;
import com.pzhuweb.sgblog.mapper.SystemUserMapper;
import com.pzhuweb.sgblog.service.RoleService;
import com.pzhuweb.sgblog.service.SystemUserService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @author 鄧浩奇
 * @classname SystemUserServiceImpl
 * @description
 * @since 2023/8/18 18:00
 **/

@Service
public class SystemUserServiceImpl extends ServiceImpl<SystemUserMapper, User> implements SystemUserService {

    @Resource
    private RoleService roleService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private RoleMapper roleMapper;

    @Override
    public ResponseResult<?> getUserList(Integer pageNum, Integer pageSize, String userName, String phoneNumber, Integer status) {
        Page<User> userPage = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(userName), User::getUserName, userName)
                .like(StringUtils.hasText(phoneNumber), User::getPhonenumber, phoneNumber)
                .eq(Objects.nonNull(status), User::getStatus, status);
        page(userPage, wrapper);
        PageVo pageVo = new PageVo(userPage.getRecords(), userPage.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult<?> getUserInfo(Long id) {
        // 根据id查询角色id
        RoleMapper baseMapper = (RoleMapper) roleService.getBaseMapper();
        List<Long> ids = baseMapper.selectRoleIdsByUserId(id);
        // 根据id查询角色信息
        List<Role> roleList = baseMapper.selectRolesByUserId(id);
        // 查询user信息
        User byId = getById(id);
        UserInfoVo user = BeanCopyUtils.copyBean(byId, UserInfoVo.class);
        // 封装
        AdminUserVo userVo = new AdminUserVo(ids, roleList, user);
        return ResponseResult.okResult(userVo);
    }

    @Override
    public ResponseResult<?> updateUser(UserDto userDto) {
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(User::getId, userDto.getId())
//                .set(User::getAvatar,userDto.getAvatar())
                .set(User::getNickName, userDto.getNickName())
                .set(StringUtils.hasText(userDto.getPhonenumber()),User::getPhonenumber, userDto.getPhonenumber())
                .set(User::getEmail, userDto.getEmail())
                .set(User::getSex, userDto.getSex())
                .set(User::getStatus, userDto.getStatus());
        update(wrapper);
        // 处理角色id

        RoleMapper baseMapper = (RoleMapper) roleService.getBaseMapper();
        List<Long> roleIds = userDto.getRoleIds();
        baseMapper.deleteRoleIdsByUserId(userDto.getId());
//        roleIds.forEach(roleId -> baseMapper.saveRoleIdsByUserId(userDto.getId(),roleId));
        for (Long roleId : roleIds) {
            baseMapper.saveRoleIdsByUserId(userDto.getId(), roleId);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<?> changeStatus(UserStatusDto statusDto) {
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(User::getId, statusDto.getUserId())
                .set(User::getStatus, statusDto.getStatus());
        update(wrapper);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<?> addUser(AddUserDto addUserDto) {
        if (!StringUtils.hasText(addUserDto.getEmail())) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_ISNULL);
        }
        if (!StringUtils.hasText(addUserDto.getPhonenumber())) {
            throw new SystemException(AppHttpCodeEnum.PHONE_NUMBER_ISNULL);
        }
        if (!StringUtils.hasText(addUserDto.getUserName())) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_ISNULL);
        }
        if (!StringUtils.hasText(addUserDto.getPassword())) {
            throw new SystemException(AppHttpCodeEnum.PASSWORD_ISNULL);
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getPhonenumber, addUserDto.getPhonenumber());
        if (!list(wrapper).isEmpty()) {
            throw new SystemException(AppHttpCodeEnum.PHONE_NUMBER_EXIST);
        }
        wrapper.clear();
        wrapper.eq(User::getUserName,addUserDto.getUserName());
        if (!list(wrapper).isEmpty()) {
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        addUserDto.setPassword(passwordEncoder.encode(addUserDto.getPassword()));
        User user = BeanCopyUtils.copyBean(addUserDto, User.class);
        save(user);
        List<Long> roleIds = addUserDto.getRoleIds();
        wrapper.clear();
        for (Long roleId:roleIds) {
            roleMapper.saveRoleIdsByUserId(getOne(wrapper.eq(User::getUserName,addUserDto.getUserName())).getId(),roleId);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<?> deleteUser(List<Long> ids) {
        removeBatchByIds(ids);
        for (Long id: ids) {
            roleMapper.deleteRoleIdsByUserId(id);
        }
        return ResponseResult.okResult();
    }
}
